#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <stdlib.h>
#include "snri_module.h"


/*#define printf(...)*/

struct {
	in_addr_t my_addr;
	int mysocket;
} instance;

int sent_messages = 0;

const char * ip_to_string(in_addr_t ip) {
	static char buffer[40];
	return inet_ntop(AF_INET, &ip, buffer, sizeof(buffer));
}

const char * ip_to_string2(in_addr_t ip, char *buffer, size_t buflen) {
	return inet_ntop(AF_INET, &ip, buffer, buflen);
}

void _snri_mod_init() {
	/* register the globals here */
	snri_register_globals(2,  sizeof(instance), &instance,  sizeof(sent_messages), &sent_messages);
	
//	snri_logprintf("Test module init!\n");
}

void _snri_mod_uninit() {
//	printf("Test module uninit!\n");
}

char * get_pretty_time() {
	static char time[45];
	struct timeval t;
	snri_gettime(&t);
	
	sprintf(time, "%d:%.3d", t.tv_sec, t.tv_usec/1000);

	return time;
}

void _snri_mod_destroy() {
	snri_log(0, "%s <%s> I am dead.\n", get_pretty_time(), ip_to_string(snri_getip()));
}

void send_message_timer(int timerid, void * ip) {
	char buffer[100];
	in_addr_t target = *((in_addr_t*)ip); 
	sent_messages++;
	
	snri_log(0, "%s <%s> Timer %d expires: Sending 'hate' to %s. Sent %d total.\n", get_pretty_time(), ip_to_string(snri_getip()), timerid, ip_to_string2(target,buffer,sizeof(buffer)), sent_messages);
	snri_datagram_send(instance.mysocket, target, 9000, 5, "hate");
	
	free(ip);
}



void my_socket_function(int socket, in_addr_t source, int source_port, unsigned int data_length, char * data) {
	int delay = rand() % 200;
	char buffer[100];	
	in_addr_t * addr = malloc(sizeof(*addr));
	
	snri_log(0,"%s <%s> Got message '%s' from %s. Scheduling send for %d ms later.\n", get_pretty_time(), ip_to_string(snri_getip()), data, ip_to_string2(source,buffer,sizeof(buffer)), delay);
	
	/* schedule a packet sendout in 100ms to the destination */
	*addr = source;
	snri_timer_create(delay, &send_message_timer, addr);
}

void _snri_mod_instantiate(int argc, char * argv[], in_addr_t bootstrap_address) {
	in_addr_t my_addr = snri_getip();
	struct timeval current_time;
	char buffer[40];
	
	instance.my_addr = my_addr;
	instance.mysocket = snri_datagram_socket(my_addr, 9000 /*port*/, &my_socket_function);

	snri_gettime(&current_time);
	
	snri_log(0, "%s <%s> Started node\n", get_pretty_time(), ip_to_string(my_addr));
	
	if(bootstrap_address != INADDR_NONE) {
		/* bootstrap off someone else! */
		snri_datagram_send(instance.mysocket, bootstrap_address, 9000, 5, "love");
		snri_log(0, "%s <%s> Sent bootstrap to %s\n", get_pretty_time(), ip_to_string(my_addr), ip_to_string2(bootstrap_address,buffer,sizeof(buffer)));
	}

	return;
}


